package net.cloudcodex.client.character.detail.view;

import java.util.HashMap;
import java.util.Map;

import net.cloudcodex.client.widgets.CharacterAvatar;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.inject.Inject;

/**
 * 
 * @author ADaroussin
 */
public class CharacterDetailViewImpl extends DockLayoutPanel implements CharacterDetailView {

	public class AvatarTextArea extends DockLayoutPanel {
		private final CharacterAvatar avatar;
		private final TextArea textArea = new TextArea();

		public AvatarTextArea(String characterName, String characterIcon, String value) {
			super(Unit.PX);
			avatar = new CharacterAvatar(characterIcon, characterName);
			avatar.resize("50", "50");
			textArea.setValue(value);
			textArea.addValueChangeHandler(stringChangeHandler);
			addWest(avatar, 50);
			add(textArea);
		}

		public CharacterAvatar getAvatar() {
			return avatar;
		}

		public TextArea getTextArea() {
			return textArea;
		}
	}

	public class LabelTextBox extends DockLayoutPanel {
		private final Label label = new Label();
		private final TextBox textBox = new TextBox();

		public LabelTextBox(String label, String value) {
			super(Unit.PX);
			this.label.setText(label + message.getLabelSeparation());
			textBox.setValue(value);
			textBox.addValueChangeHandler(stringChangeHandler);
			addWest(this.label, 50);
			add(textBox);
		}

		public Label getLabel() {
			return label;
		}

		public TextBox getTextBox() {
			return textBox;
		}
	}

	private final Message message;

	private final Button cancelButton;
	private final Button updateButton;
	private final CharacterAvatar avatar = new CharacterAvatar();
	private final LabelTextBox characterName;
	private final LabelTextBox characterIcon;
	private final CheckBox lockedCheckBox;
	private final CheckBox deadCheckBox;
	private final TextArea publicDescription = new TextArea();
	private final TextArea privateDescription = new TextArea();
	private final TextArea personnalNote = new TextArea();
	private final FlowPanel notesPanel = new FlowPanel();
	private final Map<Long, AvatarTextArea> notes = new HashMap<Long, AvatarTextArea>();
	private final FlowPanel aliasesPanel = new FlowPanel();
	private final Map<Long, LabelTextBox> aliases = new HashMap<Long, LabelTextBox>();

	private final ValueChangeHandler<String> stringChangeHandler = new ValueChangeHandler<String>() {
		@Override
		public void onValueChange(ValueChangeEvent<String> event) {
			ValueChangeEvent.fire(CharacterDetailViewImpl.this, event.getValue());
		};
	};

	private final ValueChangeHandler<Boolean> booleanChangeHandler = new ValueChangeHandler<Boolean>() {
		@Override
		public void onValueChange(ValueChangeEvent<Boolean> event) {
			ValueChangeEvent.fire(CharacterDetailViewImpl.this, event.getValue());
		};
	};

	@Inject
	public CharacterDetailViewImpl(Message message) {
		super(Unit.PX);
		this.message = message;

		cancelButton = new Button(message.getButtonCancel());
		updateButton = new Button(message.getButtonUpdate());
		characterName = new LabelTextBox(message.getLabelName(), null);
		characterName.getTextBox().addValueChangeHandler(stringChangeHandler);
		characterIcon = new LabelTextBox(message.getLabelIcon(), null);
		characterIcon.getTextBox().addValueChangeHandler(stringChangeHandler);
		lockedCheckBox = new CheckBox(message.getLabelLocked());
		lockedCheckBox.addValueChangeHandler(booleanChangeHandler);
		deadCheckBox = new CheckBox(message.getLabelDead());
		deadCheckBox.addValueChangeHandler(booleanChangeHandler);
		publicDescription.addValueChangeHandler(stringChangeHandler);
		privateDescription.addValueChangeHandler(stringChangeHandler);
		personnalNote.addValueChangeHandler(stringChangeHandler);

		final DockLayoutPanel publicPanel = new DockLayoutPanel(Unit.PX);
		publicPanel.addWest(avatar, 100);
		final Label publicDescriptionLabel = new Label(message.getLabelPublicDescription());
		publicPanel.addNorth(publicDescriptionLabel, 20);
		publicPanel.add(publicDescription);
		addNorth(publicPanel, 120);

		final DisclosurePanel advancedPanel = new DisclosurePanel();
		final Label advancedLabel = new Label(message.getLabelAdvancedInformation());
		advancedPanel.setHeader(advancedLabel);
		final DockLayoutPanel advancedContentPanel = new DockLayoutPanel(Unit.PX);
		advancedContentPanel.addNorth(characterName, 20);
		advancedContentPanel.addNorth(characterIcon, 20);

		final LayoutPanel checkBoxPanel = new LayoutPanel();
		checkBoxPanel.add(lockedCheckBox);
		checkBoxPanel.setWidgetLeftWidth(lockedCheckBox, 0, Unit.PX, 50, Unit.PX);
		checkBoxPanel.add(deadCheckBox);
		checkBoxPanel.setWidgetLeftWidth(deadCheckBox, 50, Unit.PX, 50, Unit.PX);
		advancedContentPanel.addNorth(checkBoxPanel, 20);
		advancedContentPanel.addNorth(aliasesPanel, 50);

		advancedPanel.setContent(advancedContentPanel);
		addNorth(advancedPanel, 130);

		final Label privateDescriptionLabel = new Label(message.getLabelPrivateDescription());
		addNorth(privateDescriptionLabel, 20);
		addNorth(privateDescription, 100);

		final Label personnalNoteLabel = new Label(message.getLabelPersonnalNote());
		addNorth(personnalNoteLabel, 20);
		addNorth(personnalNote, 100);

		final Label noteLabel = new Label(message.getLabelNotePlayer());
		addNorth(noteLabel, 20);
		
		final LayoutPanel buttonPanel = new LayoutPanel();
		buttonPanel.add(updateButton);
		buttonPanel.setWidgetLeftWidth(updateButton, 0, Unit.PX, 50, Unit.PX);
		buttonPanel.add(cancelButton);
		buttonPanel.setWidgetLeftWidth(cancelButton, 50, Unit.PX, 50, Unit.PX);
		addSouth(buttonPanel, 30);
		
		add(notesPanel);
	}

	@Override
	public HasClickHandlers getCancelButton() {
		return cancelButton;
	}

	@Override
	public HasClickHandlers getUpdateButton() {
		return updateButton;
	}

	@Override
	public void setUpdateButtonEnabled(boolean enabled) {
		updateButton.setEnabled(enabled);
	}

	@Override
	public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Object> handler) {
		return addHandler(handler, ValueChangeEvent.getType());
	}

	@Override
	public void displayAdvancedInformation(boolean display) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setCharacter(String name, String icon) {
		avatar.initComponent(icon, name);
		characterName.getTextBox().setValue(name);
		characterIcon.getTextBox().setValue(icon);
	}

	@Override
	public Boolean isLocked() {
		return lockedCheckBox.getValue();
	}

	@Override
	public void setLocked(Boolean locked) {
		lockedCheckBox.setValue(locked);
	}

	@Override
	public Boolean isDead() {
		return deadCheckBox.getValue();
	}

	@Override
	public void setDead(Boolean dead) {
		deadCheckBox.setValue(dead);
	}

	@Override
	public String getPublicDescription() {
		return publicDescription.getValue();
	}

	@Override
	public void setPublicDescription(String description, boolean editable) {
		publicDescription.setValue(description);
		publicDescription.setEnabled(editable);
	}

	@Override
	public String getPrivateDescription() {
		return privateDescription.getValue();
	}

	@Override
	public void setPrivateDescription(String description, boolean editable) {
		privateDescription.setValue(description);
		privateDescription.setEnabled(editable);
	}

	@Override
	public String getPersonnalNote() {
		return personnalNote.getValue();
	}
	
	@Override
	public void setPersonnalNote(String note) {
		personnalNote.setValue(note);
	}
	
	@Override
	public String getNote(Long characterId) {
		final AvatarTextArea avatarTextArea = notes.get(characterId);
		return avatarTextArea.getTextArea().getValue();
	}

	@Override
	public void setNote(Long characterId, String characterName, String icon, String note, boolean editable) {
		AvatarTextArea avatarTextArea = notes.get(characterId);
		if (avatarTextArea == null) {
			// Create note
			avatarTextArea = new AvatarTextArea(characterName, icon, note);
			notes.put(characterId, avatarTextArea);
			notesPanel.add(avatarTextArea);
		} else {
			// Update note
			avatarTextArea.getAvatar().initComponent(icon, characterName);
			avatarTextArea.getTextArea().setValue(note);
		}
		avatarTextArea.getTextArea().setEnabled(editable);
	}

	@Override
	public String getAlias(Long characterId) {
		final LabelTextBox labelTextBox = aliases.get(characterId);
		return labelTextBox.getTextBox().getValue();
	}

	@Override
	public void setAlias(Long characterId, String characterName, String alias) {
		LabelTextBox labelTextBox = aliases.get(characterId);
		if (labelTextBox == null) {
			// Create alias
			labelTextBox = new LabelTextBox(characterName, alias);
			aliases.put(characterId, labelTextBox);
			aliasesPanel.add(labelTextBox);
		} else {
			// Update alias
			labelTextBox.getTextBox().setValue(alias);
		}
	}

}
